﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using umbraco.MacroEngines;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;

namespace Khaaaantest
{
    public class Utilities
    {

        /// <summary>
        /// Returns a list of all the descendant document types, starting from the supplied node
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static List<int> RecursivelyGetDescendantIds(DocumentType node)
        {
            var childIds = new List<int> {node.Id};

            var childDocumentTypes = DocumentType.GetAllAsList().Where(x => x.MasterContentType == node.Id);
            foreach (var childDocumentType in childDocumentTypes)
            {
                childIds.AddRange(RecursivelyGetDescendantIds(childDocumentType));
            }

            return childIds;
        }

        /// <summary>
        /// This method deletes documents types related to KhaaaantestContest
        /// </summary>
        /// <param name="descendantIds"></param>
        public static void RecursivelyDeleteKhaaaantestContestDocumentTypes(List<int> descendantIds)
        {
            // Transform that list of all the descentant document types ids into a string
            var descendantIdsString = "";
            foreach (var descendantId in descendantIds)
            {
                if (descendantIdsString != "")
                {
                    descendantIdsString += ", ";
                }
                descendantIdsString += descendantId;
            }

            var sqlHelper = Application.SqlHelper;

            // Query to get all the leaf document types (no children for them)
            var script = "SELECT nodeId " +
                         "FROM cmsContentType " +
                         "WHERE nodeId IN (" + descendantIdsString + ") " +
                         "AND nodeId NOT IN (SELECT masterContentType FROM cmsContentType " +
                         "WHERE nodeId IN (" + descendantIdsString + "))";
            var reader = sqlHelper.ExecuteReader(script);

            // Delete the leaf document types
            if (reader.Read())
            {
                var docTypeId = reader.GetInt("nodeId");
                var docTypeToDelete = DocumentType.GetAllAsList().SingleOrDefault(x => x.Id == docTypeId);
                if (docTypeToDelete != null)
                {
                    docTypeToDelete.delete();
                    descendantIds.Remove(docTypeId);
                }
            }

            // Repeat if there are document types left
            if (descendantIds.Any())
            {
                RecursivelyDeleteKhaaaantestContestDocumentTypes(descendantIds);
            }

        }

        /// <summary>
        /// This method takes an Umbraco node Id and either returns the associated file URL or an empty string.
        /// </summary>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        public static string GetMediaSrcOrEmptyString(string nodeId)
        {
            if (nodeId != "")
            {
                dynamic mediaItem = new DynamicNode(Convert.ToInt32(nodeId));
                return mediaItem.umbracoFile;
            }
            return "";
        }

        /// <summary>
        /// Gets the first few words of a string, controlled by number of characters. Will cut at the next whitespace.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="numberOfChar"></param>
        /// <returns></returns>
        public static string GetFirstFewWords(string input, int numberOfChar)
        {
            if (numberOfChar < input.Length)
            {
                // Starts at the supplied appropiate number of characters and finds the next whitespace until the end of the string.
                for (var i = numberOfChar; i < input.Length; i++)
                {
                    // Find the next space, this may not find any ' '
                    if (Char.IsWhiteSpace(input[i]))
                    {
                        // From that space, cut at the previous a-z, 0-9 char and append ...
                        return CutStringUntilItEndsWithaz09(input.Substring(0, i));
                    }
                }
            }

            // Nothing to do so clean the whitespaces as precaution
            return input.Trim();
        }

        /// <summary>
        /// This method removes characters from the string until it reaches a-z, A-Z or 0-9. This is usefull so that cut strings don't end with commas and such.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string CutStringUntilItEndsWithaz09(string input)
        {
            var transit = input;
            for (var i = transit.Length; i > 0; i--)
            {
                if (Regex.IsMatch((transit[i - 1] + ""), "[a-zA-Z0-9]"))
                {
                    return transit;
                }
                // Else, cut that character
                transit = transit.Substring(0, i - 1);
            }
            return string.Empty;
        }

    }
}